from django.utils.translation import ugettext_lazy as _
try:
	from django.contrib.gis.db import models
except ImportError:
	from django.db import models

import libxml2

__all__ = ["OpenSearch"]

class OpenSearch(object):
	ShortName = None
	Description = None
	Url = [{ "type" : "application/xhtml+xml",
		 "description" : _("HTML"),
		 "template" : "/duetopia/%(app)s/%(model)s/?%(spec)s" },
	       { "type" : "application/json",
		 "description" : _("JSON"),
		 "template" : "/duetopia/%(app)s/%(model)s/json/?%(spec)s" },
	       { "type" : "application/vnd.google-earth.kml+xml",
		 "description" : _("KML"),
		 "template" : "/duetopia/%(app)s/%(model)s/kml/?%(spec)s" }]
	namespaces = {}
	search_terms = []
	display_fields = []
	
	def __init__(self, model):
		self.model = model

	@classmethod
	def contribute_to_class(cls, model, name):
		search = cls(model)
		setattr(model._meta, "search", search)
		
	@property
	def description(self):
		doc = libxml2.newDoc("1.0")
		
		osd = libxml2.newNode("OpenSearchDescription")
		osns = osd.newNs("http://a9.com/-/spec/opensearch/1.1/", None)
		osd.setNs(osns)
		for ns in self.namespaces:
			osd.newNs(self.namespaces[ns], ns)
		doc.addChild(osd)

		shortName = self.ShortName or _("Duetopia %(name)s Search") % \
					    {"name" : unicode(self.model._meta.verbose_name)}
		osd.newChild(None, "ShortName", unicode(shortName))

		description = self.Description or _("Search Duetopia for geospatial data")
		osd.newChild(None, "Description", unicode(description))

		### optional tags that can appear zero or one time and cannot be
		### determined automatically
		for optional_tag in ["Contact", "LongName", "Developer", "Attribution",
				     "SyndicationRight", "AdultContent"]:
			if hasattr(self, optional_tag):
				tag = getattr(self, optional_tag)
				osd.newChild(None, optional_tag, unicode(tag))
				
		### optional tags that can appear zero or more times and cannot be
		### determined automatically
		for optional_tag in ["Language", "InputEncoding", "OutputEncoding"]:
			if not hasattr(self, optional_tag):
				continue
			tags = getattr(self, optional_tag)
			if tags and not isinstance(tags, list) and not isinstance(tags, tuple):
				tags = [tags]
			if tags:
				for tag in tags:
					osd.newChild(None, optional_tag, unicode(tag))

		for u in self.templates:
			url = osd.newChild(None, "Url", None)
			url.setProp("type", u["type"])
			url.setProp("template", u["template"])
		data = doc.serialize("utf-8", True)
		doc.freeDoc()
		return data

	@property
	def templates(self):
		urls = self.Url
		if not isinstance(urls, list) and not isinstance(urls, tuple):
			urls = [urls]
		search_spec = []
		for term in self.search_terms:
			search_spec.append("%(name)s={%(query)s}" % term)
		search_spec = "&".join(search_spec)
		def _get_templates():
			for u in urls:
				v = u.copy()
				v["template"] = u["template"] % {
					"app" : self.model._meta.app_label,
					"model" : self.model._meta.module_name,
					"spec" : search_spec,
				}
				yield v
		return list(_get_templates())

